﻿using System.Diagnostics;

namespace DimensionsHelper.LanguageService;

/// <summary>
///     <see cref="Lexer" />使用的文本扫描指针。
/// </summary>
/// <param name="text">扫描的文本内容</param>
/// <param name="position">当前的指针位置</param>
public struct TextPointer(string text, int position = -1)
{
    private readonly int _length = text.Length;


    /// <summary>
    ///     当前的文本指针的位置
    /// </summary>
    public int Position { get; private set; } = position;


    /// <summary>
    ///     当前文本指针的行数，1开始。
    /// </summary>
    public int Line { get; private set; } = 1;


    public readonly int GetTextPosition()
    {
        return Position < 0 ? 0 : Position;
    }


    /// <summary>
    ///     当前字符，如果没有调用过<see cref="Next" />方法，将返回'\0'
    /// </summary>
    public readonly char Current => Position >= 0 && Position < _length ? text[Position] : '\0';


    /// <summary>
    ///     下一个字符，到末尾时将返回'\0'
    /// </summary>
    public char Next()
    {
        Position++;

        char ch = Current;
        if (ch == '\n')
        {
            Line++;
        }

        return ch;
    }


    /// <summary>
    ///     如果已经到文本结尾，返回<see langword="true" />
    /// </summary>
    public readonly bool Eof()
    {
        return Position >= _length;
    }


    /// <summary>
    ///     跳过指定数目的字符数
    /// </summary>
    public void Step(int charNumber)
    {
        Debug.Assert(charNumber >= 0);
        while (charNumber > 0)
        {
            Next();
            charNumber--;
        }
    }


    /// <summary>
    ///     获取当前位置的下一个字符，如果超过长度，返回'\0'
    /// </summary>
    public readonly char Ahead()
    {
        int nextPos = Position + 1;
        return nextPos >= 0 && nextPos < _length ? text[nextPos] : '\0';
    }
}